package ee.fujitsu.entity.state;

import java.io.Console;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import ee.fujitsu.common.Printer;
import ee.fujitsu.entity.Customer;
import ee.fujitsu.entity.JournalRecord;
import ee.fujitsu.entity.Movie;



/**
 * entity for state pattern implementation
 * include 3 Maps with different movie state
 * include state of store where change happens.
 */

/**
 * @author Andrei
 *
 * 10.09.2012	
 */
public class Store {

	/** The store state. */
	private State storeState;
	
	/** The rented state. */
	private State rentedState;
	
	/** The movies store. */
	private Map<Integer, Movie> moviesStore = new HashMap<Integer, Movie>();
	
	/** The movies rent. */
	private Map<Integer, Movie> moviesRent = new HashMap<Integer, Movie>();
	
	/** The movies deleted. */
	private Map<Integer, Movie> moviesDeleted = new HashMap<Integer, Movie>();
	
	/** The state. */
	private State state = storeState;
		
	/**
	 * Instantiates a new store.
	 *
	 * @param moviesStore the movies store
	 * @param moviesRent the movies rent
	 * @param moviesDeleted the movies deleted
	 */
	public Store (Map<Integer, Movie> moviesStore, 
			Map<Integer, Movie> moviesRent,
			Map<Integer, Movie> moviesDeleted) {
		this.moviesStore = moviesStore;
		this.moviesRent = moviesRent;
		this.moviesDeleted = moviesDeleted;
		storeState = new StateInStore();
		rentedState = new StateRented();
		state = storeState;
	}
		
		/**
		 * Gets the state.
		 *
		 * @return the state
		 */
		public State getState() {
			return state;
		}

		/**
		 * Sets the state.
		 *
		 * @param state the state to set
		 */
		public void setState(State state) {
			this.state = state;
		}

		  /**
  		 * Rent film from store.
  		 *
  		 * @param startDate the start date
  		 * @param expectedEnd the expected end
  		 * @param realEnd the real end
  		 * @param client the client
  		 * @param bonus the bonus
  		 * @return the journal record
  		 */
		public JournalRecord rentFilm(Date startDate,
				Date expectedEnd,
				Date realEnd,
				Customer client,
				boolean bonus) {
			return state.rentFilm(moviesStore, moviesRent, startDate, expectedEnd, realEnd, client, bonus);
		}

		/**
		 * Return film to store from rent
		 * 
		 * Use {@link #returnFilm()} changing.
		 */
		public void returnFilm() {
			state = rentedState;
			state.returnFilm(moviesStore, moviesRent);
		}

		/**
		 * delete film in store
		 * 
		 * Use {@link #deleteFilm()} for delete.
		 */
		public void deleteFilm(int index) {
			state = storeState;
			if (state.deleteFilm(moviesStore, moviesDeleted, index)) 
				Printer.print("Films quantity: " + moviesStore.size());
			else
				Printer.print("Cant delete film");
		}

		  /**
  		 * return Count all films.
  		 *
  		 * @return the int
  		 */
		public int countAllFilms() {
			return moviesStore.size() + moviesRent.size();
		}
		
		  /**
  		 * return Count store films.
  		 *
  		 * @return the int
  		 */
		public int countStoreFilms() {
			return moviesStore.size() ;
		}

		
		  /**
  		 * Add film to store.
  		 *
  		 */
		public void addFilm() {
			state = storeState;
			Printer.print("Films quantity: " + moviesStore.size());
			state.addFilm(moviesStore);
			Printer.print("Films quantity in store: " + moviesStore.size());
		}

		/**
		 * Change film type throw interactive process
		 * 
		 * Use {@link #changeFilm(Store store)} changing.
		 *
		 */
		public void changeFilm(int index) {
			state = storeState;
			state.changeFilm(moviesStore, index);
		}
		  
  		/**
  		 * private common method for result output.
  		 *
  		 * @param message the message
  		 * @return the movie index
  		 */
		public int getMovieIndex(String message) {
			Console console = System.console();
			Printer.print("Films quantity: " + countStoreFilms());
			int i = 0;
			Printer.print("Film id \t Title");
			Printer.print("--------------------------------");
			Map<Integer, Movie> movies = new HashMap<Integer, Movie>();
			if (state == storeState)
				movies = moviesStore;
			else
				movies = moviesRent;
			for (Map.Entry<Integer, Movie> entry : movies.entrySet()) {
				Printer.print(entry.getKey() + "\t\t" + entry.getValue().getTitle());
				if (i++ > 10)
					break;
			}
			int index = Integer.valueOf(console
					.readLine(message));

			return index;

		}
}
